﻿using System;
using System.Windows.Forms;
using Main.Menus.Submenus;
using Main.Structure;
using Main.Substructure;
using System.IO;

namespace Main.Menus
{
    /// <summary>
    /// This is the application for viewing/editing/adding/removing clients.
    /// </summary>
    public partial class ClientManager : Form
    {
        private ManageClient MC;
        private AddClient AC;
        private Timer dataModificationTimer = new Timer();
        private Timer dataAdditionTimer = new Timer();
        private uint selectedID = 0;
        private int oldKernelCount = 0;

        /// <summary>
        /// The class constuctor.
        /// </summary>
        public ClientManager()
        {
            InitializeComponent();
            dataModificationTimer.Tick += new EventHandler(dataModificationTimer_Tick);
            dataAdditionTimer.Tick += new EventHandler(dataAdditionTimer_Tick);
            // Begins its own method.
            Main();
        }

        /// <summary>
        /// This method is called after every interval of the dataAdditionTimer tick.
        /// This method checks for any newly created clients and updates the list view.
        /// </summary>
        private void dataAdditionTimer_Tick(object sender, EventArgs e)
        {
            if (AC != null && AC.Visible)
            {
                if (Kernel.Clients.Count != oldKernelCount)
                    PopulateClientList();
            }
            else { dataAdditionTimer.Stop(); }
        }

        /// <summary>
        /// This method is called after every interval of the dataModificationTimer tick.
        /// This method checks for any updates to the client being modified and updates it in the list view.
        /// </summary>
        private void dataModificationTimer_Tick(object sender, EventArgs e)
        {
            if (MC != null && MC.Visible)
            {
                Client client;
                Kernel.Clients.TryGetValue(selectedID, out client);
                listViewClientList.Items[(int)(selectedID - 1)].SubItems[1].Text = client.FirstName;
                listViewClientList.Items[(int)(selectedID - 1)].SubItems[2].Text = client.LastName;
                listViewClientList.Items[(int)(selectedID - 1)].SubItems[3].Text = client.Street;
                listViewClientList.Items[(int)(selectedID - 1)].SubItems[4].Text = client.City;
                listViewClientList.Items[(int)(selectedID - 1)].SubItems[5].Text = client.State;
                listViewClientList.Items[(int)(selectedID - 1)].SubItems[6].Text = client.Zip;
                listViewClientList.Items[(int)(selectedID - 1)].SubItems[7].Text = client.Phone;
            }
            else { dataModificationTimer.Stop(); }
        }

        /// <summary>This method contains all of the code we want to run before the form is loaded.</summary>
        private void Main()
        {
            #region Populate Client List
            PopulateClientList();
            #endregion
        }

        /// <summary>This method loads all of the clients into an easily readable list.</summary>
        private bool PopulateClientList()
        {
            // We wrap a try/catch around this because if an exception is thrown, there was an error.
            // That means we need to say something went wrong so we can debug.
            try
            {
                listViewClientList.Items.Clear(); // Clear it before we populate it, so no duplicates.

                // For every client that has been loaded to the Kernel, we need to create
                // it's own spot in the viewable list.
                foreach (Client client in Kernel.Clients.Values)
                {
                    ListViewItem listItem = new ListViewItem(); // Create a new ListViewItem to assign data to.

                    #region Client List Documentation
                    /*
                     * Initial list item text is the account id.
                     * The first subitem is the client's first name
                     * The second subitem is the client's last name
                     * The third subitem is the client's street
                     * The fourth subitem is the client's city
                     * The fifth subitem is the client's state
                     * The sixth subitem is the client's zipcode
                     * The last subitem is the client's phone
                     */
                    #endregion

                    //ListViewItem.Text is the first column. Each subitem afterward is the next column.
                    listItem.Text = client.AccountID.ToString();
                    listItem.SubItems.Add(client.FirstName);
                    listItem.SubItems.Add(client.LastName);
                    listItem.SubItems.Add(client.Street);
                    listItem.SubItems.Add(client.City);
                    listItem.SubItems.Add(client.State);
                    listItem.SubItems.Add(client.Zip);
                    listItem.SubItems.Add(client.Phone);

                    // Now we add all of that information to the viewable client list as an item.
                    listViewClientList.Items.Add(listItem);
                }
                // If no programmer errors occured, we return true so we know everything went okay.
                return true;
            }
            catch (Exception) { return false; }
        }

        /// <summary>
        /// This method is called when the user wants to edit a client's information.
        /// It selects the client the user wants to edit and then loads the information in a separate window.
        /// </summary>
        private void btnManageClient_Click(object sender, EventArgs e)
        {
            var selectionCount = listViewClientList.SelectedItems.Count; // For simplicity.
            if (selectionCount != 1) { return; } // Right now we only want to let the user edit one client at a time.

            // For each client that the user has selected... (should only be 1 for now)
            foreach (ListViewItem listItem in listViewClientList.SelectedItems)
            {
                uint accountID = 0; // Assign 0 to this variable for error-checking.
                UInt32.TryParse(listItem.Text, out accountID); // Parse the account ID of the client the user has selected.
                if (accountID == 0) { return; } // If the value is still 0, something is way wrong. Don't continue.
                Client client; // Create an empty Client variable.
                Kernel.Clients.TryGetValue(accountID, out client); // Load the created Client variable by choosing a client in the kernel that has the account ID the user selected.
                if (client == null) { return; } // If the client could not be loaded, something is way wrong. Don't continue.
                MC = new ManageClient(client); // Create a new window and pass it the client's information.
                Utilities.LaunchMenu(MC); // Show the user's information in a way that it can be edited.
                selectedID = accountID; // Set the selectedID so the timer code knows which data to update.
                dataModificationTimer.Interval = 500; // Set the timer to run the code every half second.
                dataModificationTimer.Start(); // Start the timer.
            }
        }

        /// <summary>
        /// This method is called when the user wants to add a new client.
        /// This method brings up the client creation screen.
        /// </summary>
        private void btnAddClient_Click(object sender, EventArgs e)
        {
            AC = new AddClient();
            Utilities.LaunchMenu(AC);
            oldKernelCount = Kernel.Clients.Count;
            dataAdditionTimer.Interval = 500;
            dataAdditionTimer.Start();
        }

        private void btnRemoveClient_Click(object sender, EventArgs e)
        {
            var selectionCount = listViewClientList.SelectedItems.Count;
            if (selectionCount != 1) { return; }

            foreach (ListViewItem listItem in listViewClientList.SelectedItems)
            {
                uint accountID = 0;
                UInt32.TryParse(listItem.Text, out accountID);
                if (accountID == 0) { return; }
                DialogResult result = Utilities.Message("Are you sure that you would like to remove this client? Cannot be undone.", "Remove Client?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (result != System.Windows.Forms.DialogResult.Yes) { return; }
                if (Database.Clients.Remove(Kernel.Clients[accountID]))
                    Utilities.Message("Client successfully removed!", "Client Removed!", MessageBoxButtons.OK, MessageBoxIcon.Information);
                else Utilities.Message("Client could not be removed.", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                PopulateClientList();
            }
        }
    }
}
